package xin.nick.common.core.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.util.List;
import java.util.Objects;

/**
 * ip获取
 *
 * @author Nick
 * @since 2022/1/24
 */
@Slf4j
public class IpUtil {

    private IpUtil() {

    }

    public static final String UNKNOWN = "unknown";
    public static final String LOCAL_IP = "127.0.0.1";
    public static final int IP_LENGTH = 15;
    public static final String SEPARATOR = ",";

    public static String getIpAddress(HttpServletRequest request) {
        String ipAddress = getIpFromHeader(request);

        try {

            // 如果是本地IP则尝试从网卡获取
            if (CharSequenceUtil.isBlank(ipAddress) || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (LOCAL_IP.equals(ipAddress)) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    inet = InetAddress.getLocalHost();
                    if (Objects.nonNull(inet)) {
                        ipAddress = inet.getHostAddress();
                    }

                }
            }

            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照‘,‘分割
            // "***.***.***.***".length()
            if (ipAddress != null && ipAddress.length() > IP_LENGTH && ipAddress.indexOf(SEPARATOR) >= 1) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(SEPARATOR));
            }

        } catch (Exception e) {
            ipAddress = "";
        }

        return ipAddress;
    }

    /**
     * 从请求头获取IP
     * @param request
     * @return
     */
    public static String getIpFromHeader(HttpServletRequest request) {
        String ipAddress = "";

        // 尝试从请求头获取
        List<String> ipHeaderList = CollUtil.newArrayList("x-forwarded-for", "Proxy-Client-IP", "WL-Proxy-Client-IP");
        for (String header : ipHeaderList) {
            if (CharSequenceUtil.isBlank(ipAddress) || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader(header);
            } else {
                break;
            }
        }

        return ipAddress;
    }


}